package dao

import (
	"context"
	"errors"
	"github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"time"
)

var (
	ErrUserDuplicateEmail  = errors.New("邮箱冲突！")
	ErrUserNotFound        = gorm.ErrRecordNotFound
	ErrUserProfileNotFound = gorm.ErrRecordNotFound
)

type UserDAO struct {
	db *gorm.DB
}

type User struct {
	Id       int64  `gorm:"primaryKey,autoIncrement"`
	Email    string `gorm:"unique"`
	Password string
	Ctime    int64
	Utime    int64
}

type UserProfile struct {
	Id    int64  `gorm:"primaryKey,autoIncrement"`
	Uid   int64  `gorm:"unique"`
	Name  string `gorm:"unique"`
	Birth string
	Intro string
	Ctime int64
	Utime int64
}

func NewUserDAO(db *gorm.DB) *UserDAO {
	return &UserDAO{db: db}
}

func (dao UserDAO) Insert(c context.Context, u User) error {
	now := time.Now().UnixMilli()
	u.Ctime = now
	u.Utime = now
	err := dao.db.WithContext(c).Create(&u).Error
	if me, ok := err.(*mysql.MySQLError); ok {
		const uniqueIndexErrNo uint16 = 1062
		if me.Number == uniqueIndexErrNo {
			return ErrUserDuplicateEmail
		}
	}
	return err
}

func (dao UserDAO) CreateUserProfile(c context.Context, profile UserProfile) error {
	now := time.Now().UnixMilli()
	profile.Utime = now
	profile.Ctime = now
	return dao.db.WithContext(c).Create(&profile).Error
}

func (dao UserDAO) UpdateUserProfile(ctx context.Context, profile UserProfile) error {
	profile.Utime = time.Now().UnixMilli()
	return dao.db.Save(&profile).Error
}

func (dao UserDAO) FindByEmail(ctx context.Context, email string) (User, error) {
	var user User
	err := dao.db.WithContext(ctx).Where("email=?", email).First(&user).Error
	return user, err
}

func (dao UserDAO) FindProfileByUid(c context.Context, uid int64) (UserProfile, error) {
	var up UserProfile
	err := dao.db.WithContext(c).Where("uid=?", uid).First(&up).Error
	return up, err
}
func (dao UserDAO) FindProfileByName(c context.Context, name string) (UserProfile, error) {
	var up UserProfile
	err := dao.db.WithContext(c).Where("name=?", name).First(&up).Error
	return up, err
}
